package com.ndood.core.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import org.apache.commons.lang.StringUtils;

public class DateUtil {
	public static final long daySpan = 24 * 60 * 60 * 1000;
	/** yyyy-MM-dd HH:mm:ss */
	public static final String TIME_FORMAT_NORMAL = "yyyy-MM-dd HH:mm:ss";
	/** yyyy-MM-dd */
	public static final String DATE_FORMAT_NORMAL = "yyyy-MM-dd";
	/** yyyy.MM.dd */
	public static final String DATE_FORMAT_DOT = "yyyy.MM.dd";
	/** yyyyMMdd */
	public static final String DATE_FORMAT_NO_MINUS = "yyyyMMdd";
	/** yyMMdd */
	public static final String DATE_FORMAT_NO_MINUS_SHORT = "yyMMdd";
	/** yyyy-MM */
	public static final String MONTH_FORMAT_NORMAL = "yyyy-MM";
	/** MM-dd */
	public static final String MONTH_DAY_FORMAT = "MM-dd";
	/** yyyyMMdd */
	public static final String DATE_FORMAT_SHORT = "yyyyMMdd";
	/** yyyyMM */
	public static final String MONTH_FORMAT = "yyyyMM";
	/** yyyy.MM */
	public static final String MONTH_FORMAT_DOT = "yyyy.MM";
	/** yyyyMMddHHmm */
	public static final String DATE_FORMAT_MINUTE = "yyyyMMddHHmm";
	/** MM/dd/yyyy HH:mm:ss **/
	public static final String MONTH_DAY_YEAR_HOUR_MINUTE = "MM/dd/yyyy HH:mm:ss";

	/**
	 * 判断参数year、month、day能否组成一个合法的日期。
	 *
	 * @param month
	 *            月份，合法月份范围是 1-12
	 * @param day
	 *            日数
	 * @param year
	 *            年份，必须大于1900
	 * @return
	 */
	public static boolean isDate(int month, int day, int year) {
		if (year < 1900) {
			return false;
		}
		if (month < 1 || month > 12) {
			return false;
		}
		if (day < 1 || day > 31) {
			return false;
		}

		// 判断年份是否为闰年
		@SuppressWarnings("unused")
		boolean leapYear = isLeapYear(year);
		// 获得该年该月的最大日期
		int maxD = getMaxDay(year, month);
		if (day > maxD) {
			return false;
		}

		return true;
	}

	/**
	 * 给定一个年份和月份，可以得到该月的最大日期。 例如 2009年1月，最大日期为31。
	 *
	 * @param year
	 *            年份，必须大于1900
	 * @param month
	 *            月份，合法月份范围是 1-12
	 * @return
	 */
	public static int getMaxDay(int year, int month) {
		if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
			return 30;
		}
		if (month == 2) {
			if (isLeapYear(year)) {
				return 29;
			} else {
				return 28;
			}
		}
		return 31;
	}

	/**
	 * 判断年份是否为闰年。
	 *
	 * @param year
	 *            年份，必须大于1900
	 * @return
	 */
	public static boolean isLeapYear(int year) {
		boolean leapYear = ((year % 400) == 0);
		if (!leapYear) {
			leapYear = ((year % 4) == 0) && ((year % 100) != 0);
		}
		return leapYear;
	}

	public static String getCurrentDateTimeStr() {
		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String formatDate = format.format(date);
		return formatDate;
	}
	
	/**
	 * yyyy-MM-dd HH:mm:ss格式串转换为日期
	 * 
	 * @param yyyy-MM-dd
	 *            HH:mm:ss 格式日期
	 * @return Date日期
	 */
	public static Date parseDate(String date) {
		return parseDate(date, "yyyy-MM-dd HH:mm:ss");
	}

	public static Date parseDate(String date, String format) {
		SimpleDateFormat sf = new SimpleDateFormat(format);
		Date rsDate = null;
		try {
			rsDate = sf.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return rsDate;
	}

	public static String getCurrentMonth() {
		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
		String formatDate = format.format(date);
		return formatDate;
	}

	/**
	 * 获取当前日期（格式为20110802）
	 */
	public static Date getCurrentDay() throws ParseException {
		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		String formatDate = format.format(date);
		Date newDate = format.parse(formatDate);
		return newDate;
	}

	/**
	 * 获取下个月的第一天
	 * 
	 * @param time
	 * @param format
	 * @return
	 */
	public static String getNextMonthFirstDay(String format) {
		java.text.SimpleDateFormat df = new java.text.SimpleDateFormat(format);
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, 1);// 当前月＋1，即下个月
		cal.set(Calendar.DATE, 1);// 将下个月1号作为日期初始值
		String currentMonth = df.format(cal.getTime());
		return currentMonth;
	}

	/**
	 * 获取下个月的最后一天
	 * 
	 * @param time
	 * @param format
	 * @return
	 */
	public static String getNextMonthLastDay(String format) {
		java.text.SimpleDateFormat df = new java.text.SimpleDateFormat(format);
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DATE, 1);// 将下2个月1号作为日期初始值
		cal.add(Calendar.MONTH, 2);// 当前月＋2，即下2个月
		cal.add(Calendar.DATE, -1);// 下2个月1号减去一天，即得到下1一个月最后一天
		String currentMonth = df.format(cal.getTime());
		return currentMonth;
	}

	public static String format(Date date) {
		if (null == date) {
			return null;
		}
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String formatDate = format.format(date);
		return formatDate;
	}

	public static String format(Date date, String formatStr) {
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		String formatDate = format.format(date);
		return formatDate;
	}

	/*
	 * 判断输入的字符串是否是合法的生日 生日不能大于当前日期,支持 yyyy-MM-dd ,yyyyMMdd MM-dd-yyyy ,yyyy年MM月dd日等
	 * @param birthday 一个日期格式的字符串
	 * @param formats 期望转换后的日期格式数组
	 */
	public static boolean isRightDate(String birthday, String[] formats) {

		// 记录传入的日期字符串，转换成日期类型
		Date birth = null;

		// 判断格式是否正确，默认值为false
		boolean isRight = false;
		for (String f : formats) {
			try {
				birth = new SimpleDateFormat(f).parse(birthday);
				// 校验日期转换后是和传入的值不相同，说明日期传入有问题
				if (!new SimpleDateFormat(f).format(birth).equals(birthday)) {
					return false;
				}
				isRight = true;
				break;
			} catch (ParseException e) {
			}
		}

		if (isRight) {
			// 获取当前日期的毫秒数
			long now = new Date().getTime();
			// 获取生日的毫秒数
			long birthTime = birth.getTime();
			// 如果当前时间小于生日，生日不合法。反之合法
			return birthTime <= now;
		} else {
			// 输入的参数类型不是日期类型，或者类型和过滤中设置的类型不匹配
			return false;
		}
	}

	/***
	 * 计算时间差，返回天数
	 * 
	 * @param b_date
	 *            大时间
	 * @param s_date
	 *            小时间
	 * @return 天数
	 */
	public static long dateSubtract(Date b_date, Date s_date) {
		if (b_date == null || s_date == null) {
			return 0;
		} else {
			long dateLong1 = b_date.getTime();
			long dateLong2 = s_date.getTime();
			long day = (dateLong1 - dateLong2) / 1000 / 60 / 60 / 24;
			return day;
		}
	}

	/**
	 * Wed Apr 05 13:44:11 CST 2017 -> 2017-04-06 03:44:11 Mon Apr 17 17:40:19 CST
	 * 2017
	 * 
	 * @param usTime
	 * @return
	 * @throws Exception
	 */
	public static String formatUTCTime(String date) throws Exception {
		SimpleDateFormat cstFormater = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
		Date gpsUTCDate = cstFormater.parse(date);
		String formatStr2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(gpsUTCDate);
		return formatStr2;
	}

	/**
	 * 20170406133029 -> 2017-04-06 13:30:29
	 * 
	 * @param timeEnd
	 * @return
	 * @throws Exception
	 */
	public static String formatNatureTime(String date) throws Exception {
		SimpleDateFormat natureFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		Date natureDate = natureFormat.parse(date);
		String formatStr2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(natureDate);
		return formatStr2;
	}

	/**
	 * 获取date之前的时间
	 * 
	 * @param min
	 * @return
	 */
	public static Date getBeforeDate(Date date, int day, int hour, int min, int sec) {
		Calendar beforeTime = Calendar.getInstance();
		beforeTime.setTime(date);
		beforeTime.add(Calendar.DATE, -day);
		beforeTime.add(Calendar.HOUR, -hour);
		beforeTime.add(Calendar.MINUTE, -min);
		beforeTime.add(Calendar.SECOND, -sec);
		Date beforeD = beforeTime.getTime();
		return beforeD;
	}

	public static Date getAfterDate(Date date, int day, int hour, int min, int sec) {
		return getAfterDate(date, 0, day, hour, min, sec);
	}

	public static Date getAfterDate(Date date, int month, int day, int hour, int min, int sec) {
		Calendar beforeTime = Calendar.getInstance();
		beforeTime.setTime(date);
		beforeTime.add(Calendar.MONTH, month);
		beforeTime.add(Calendar.DATE, day);
		beforeTime.add(Calendar.HOUR, hour);
		beforeTime.add(Calendar.MINUTE, min);
		beforeTime.add(Calendar.SECOND, sec);
		Date beforeD = beforeTime.getTime();
		return beforeD;
	}

	public static String translateTime(String time, String format1, String format2) throws Exception {
		if (StringUtils.isEmpty(time))
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
		SimpleDateFormat fm1 = new SimpleDateFormat(format1);
		Date temp = fm1.parse(time);
		SimpleDateFormat fm2 = new SimpleDateFormat(format2);
		return fm2.format(temp);
	}

	public static Long translateTime2Long(String time, String format) throws Exception {
		SimpleDateFormat fm1 = new SimpleDateFormat(format);
		Date date = fm1.parse(time);
		return date.getTime();
	}

	public static String translateTime2String(Long time, String format) throws Exception {
		if (time == null)
			time = new Date().getTime();
		SimpleDateFormat fm1 = new SimpleDateFormat(format);
		Date date = new Date(time);
		return fm1.format(date);
	}

	/**
	 * 获取字符串格式的时间
	 * 
	 * @param date
	 * @param string
	 * @return
	 */
	public static String getStringTime(Date date, String format) {
		SimpleDateFormat fm1 = new SimpleDateFormat(format);
		return fm1.format(date);
	}

	/**
	 * 得到10位时间戳
	 * 
	 * @return
	 */
	public static String getCurrent10TimestampStr() {
		String str = new Date().getTime() + "";
		return str.substring(0, 10);
	}

	/**
	 * 得到10位时间戳
	 * 
	 * @return
	 */
	public static int getCurrent10TimestampInt() {
		String str = new Date().getTime() + "";
		return Integer.parseInt(str.substring(0, 10));
	}

	/**
	 * 将php时间戳转换成正常时间
	 */
	public static Date translatePhpTimestamp(String addtime) {
		if (StringUtils.isEmpty(addtime)) {
			return new Date();
		}
		long time = Long.valueOf(addtime);
		time = time * 1000;
		return new Date(time);
	}

	public static String createDay() {
		SimpleDateFormat fm1 = new SimpleDateFormat("yyyyMMdd");
		return fm1.format(new Date());
	}

	public static Integer createIntDay() {
		String today = createDay();
		return Integer.parseInt(today);
	}

	/**
	 * 获取指定日期所在周的第一天和最后一天,用下划线连接
	 */
	public static String getFirstDayOfMonth(Date date, String resultDateFormat) {
		// 获取当前月第一天：
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, 0);
		c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
		String first = new SimpleDateFormat(resultDateFormat).format(c.getTime());
		return first;
	}

	/**
	 * 每周的第一天
	 */
	public static String getFirstDayOfWeek(Date date, String resultDateFormat) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int d = 0;
		if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
			d = -6;
		} else {
			d = 2 - cal.get(Calendar.DAY_OF_WEEK);
		}
		cal.add(Calendar.DAY_OF_WEEK, d);
		// 所在周开始日期
		String first = new SimpleDateFormat(resultDateFormat).format(cal.getTime());
		return first;
	}
	
	/**
	 * 每周最后一天
	 */
	public static String getLastDayOfWeek(Date date, String resultDateFormat) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int d = 0;
		if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
			d = 0;
		} else {
			d = 8 - cal.get(Calendar.DAY_OF_WEEK);
		}
		cal.add(Calendar.DAY_OF_WEEK, d);
		// 所在周开始日期
		String last = new SimpleDateFormat(resultDateFormat).format(cal.getTime());
		return last;
	}

	public static void main(String[] args) {
		String firstDayOfWeek = getFirstDayOfWeek(new Date(), "M月d日");
		String lastDayOfWeek = getLastDayOfWeek(new Date(), "M月d日");
		System.out.println(firstDayOfWeek+"-"+lastDayOfWeek);
	}

	public static Date getTodayStart(Date date) {
		Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date zero = calendar.getTime();
		return zero;
	}

	public static Date getTodayEnd(Date date) {
		return getAfterDate(getTodayStart(date), 1, 0, 0, 0);
	}

	/**
	 * 20180808182823345
	 */
	public static String getCurrentTimestamp() {
		return format(new Date(), "yyyyMMddHHmmssSSS");
	}

}